from logging import getLogger

from sqlalchemy.pool import NullPool

from nevow.athena import LiveElement, expose
from nevow.flat import flatten
from nevow.loaders import stan
from nevow import tags

from zope.component import getGlobalSiteManager

from meercat.storage.interfaces import IStorage
from meercat.storage.sqlalchemy import SqlAlchemyStorage



log = getLogger('meercat.server.nevow.elements.storage')

registry = getGlobalSiteManager()

class StorageList(LiveElement):
    jsClass = u'Meercat.Storage.List'
    
    docFactory = stan(tags.div(render=tags.directive('liveElement'))[
        tags.ul(class_='StorageListActions actionList')[
            tags.li()[
                tags.a(href='#',
                       onclick="Nevow.Athena.Widget.get(this).addStorageElement(); return false;")['Add Storage']],
            tags.li()[
                tags.a(href='#',
                       onclick="Nevow.Athena.Widget.get(this).refresh(); return false;")['Refresh List']]],
        tags.ul(class_='StorageList'),])
    
    @expose
    def getStorageList(self):
        log.info('%s.getStorageList()' % (str(self),))
        return map(lambda x: x[0], registry.getUtilitiesFor(IStorage))
    
    @expose
    def deleteStorage(self, name):
        log.info('%s.deleteStorage()' % (str(self),))
        return registry.unregisterUtility(name=name, provided=IStorage)
    
    @expose
    def getAddStorageElement(self):
        log.info('%s.getAddStorageElement()' % (str(self),))
        e = StorageAddForm()
        e.setFragmentParent(self)
        
        return e

class StorageAddForm(LiveElement):
    jsClass = u'Meercat.Storage.Add'

    docFactory = stan(tags.div(class_='yui-g',
                               render=tags.directive('liveElement'))[
        tags.h1()['Add Storage'],
        tags.a(href='#',onclick='Nevow.Athena.Widget.get(this).remove(); return false;')['Close'],
        tags.form()[
            tags.ul()[
                tags.li()['Name: ', tags.input(name="name", type="text")],
                tags.li()['Schema: ', tags.input(name="schema", type="text")]],
            tags.input(value="Add Storage", type="button",
                onclick="Nevow.Athena.Widget.get(this).addStorage()")]])
    
    @expose
    def createStorage(self, name, schema):
        log.info('%s.createStorage(name=%s, schema=%s)' % (str(self),name,
                                                           schema))
        
        name = name.strip()
        schema = str(schema).strip()
        
        if not name:
            raise ValueError('A name is required')
        
        storage = SqlAlchemyStorage(name, schema, encoding='utf-8',
                                    poolclass=NullPool)
        
        registry.registerUtility(component=storage, name=name, provided=IStorage)
        
        return True    